package com.ltw.dreamer.common.network;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.stereotype.Component;

import com.ltw.dreamer.report.exception.FinancialReportException;
import com.ltw.dreamer.report.util.SeasonDate;
import com.ltw.dreamer.stock.mapper.MarketHistoryMapper;
import com.ltw.dreamer.stock.model.MarketHistory;
import com.ltw.dreamer.stock.model.MarketHistoryExample;
import com.ltw.dreamer.stock.model.MarketHistoryExample.Criteria;

@Component
public class Parser {
	public static final Logger LOGGER = Logger.getLogger(Parser.class);
	
	public static final String PAGE_URI = "http://vip.stock.finance.sina.com.cn/corp/go.php/vMS_FuQuanMarketHistory/stockid/STOCK_CODE.phtml?year=YEAR&jidu=SEASON";

	@Resource
	private WebPageReader reader = null;
	
	@Resource
	private MarketHistoryMapper mapper = null;
	
	private boolean hasMoreElement = true;
	
	public boolean hasMoreElement() {
		return this.hasMoreElement;
	}
	
	public List<MarketHistory> read(String stockCode, SeasonDate seasonDate) {
		String pageUri = PAGE_URI.replaceFirst("STOCK_CODE", stockCode)
				.replaceFirst("YEAR", Integer.toString(seasonDate.getYear()))
				.replaceFirst("SEASON", Integer.toString(seasonDate.getSeason()));
		hasMoreElement = true;
		String content = reader.read(pageUri);
		
		if (content == null) {
			LOGGER.info("HTML文件读取错误，不再抓取本股票的数据：" + stockCode);
			hasMoreElement = false;
			return new ArrayList<MarketHistory>();
		}
		Document doc = Jsoup.parse(content);
		Element element = doc.getElementById("FundHoldSharesTable");
		if (element == null) {
			LOGGER.info("HTML文件解析错误，不再抓取本股票的数据：" + stockCode);
			hasMoreElement = false;
			return new ArrayList<MarketHistory>();
		}
		Elements allRows = element.getElementsByTag("tbody").get(0).getElementsByTag("tr");
		if (allRows == null || allRows.size() <= 1) {
			LOGGER.info("历史股价信息为空，股票代码：" + stockCode);
			hasMoreElement = false;
			return new ArrayList<MarketHistory>();
		}
		
		List<MarketHistory> marketHistoryList = createMarketHistoryList(stockCode, allRows);
		if (marketHistoryList.size() == 0) {
			hasMoreElement = false; // 已经没有历史股价信息需要更新，返回false
			return new ArrayList<MarketHistory>();
		}
		return marketHistoryList;
	}
	
	private List<MarketHistory> createMarketHistoryList(String stockCode, Elements allRows) {
		List<MarketHistory> marketHistoryList = new ArrayList<MarketHistory>();
		for (int i=1; i<allRows.size(); i++) {
			try {
				MarketHistory marketHistory = new MarketHistory();
				String text = allRows.get(i).text();
				String[] rowdata = text.split("\\s");
				if (rowdata.length != 8) {
					LOGGER.info("历史股价数据出现异常，数据不全：" + text);
					continue;
				}
				
				Date priceDate = getMarketHistoryDate(rowdata[0]);
				marketHistory.setDate(priceDate);
				marketHistory.setCode(stockCode);
				marketHistory.setCreatedDate(Calendar.getInstance().getTime());
				marketHistory.setUpdatedDate(Calendar.getInstance().getTime());
				marketHistory.setOpenPrice(Double.parseDouble(rowdata[1]));
				marketHistory.setMaxPrice(Double.parseDouble(rowdata[2]));
				marketHistory.setClosePrice(Double.parseDouble(rowdata[3]));
				marketHistory.setMinPrice(Double.parseDouble(rowdata[4]));
				marketHistory.setCount(Double.parseDouble(rowdata[5]));
				marketHistory.setAmount(Double.parseDouble(rowdata[6]));
				marketHistory.setWeight(Double.parseDouble(rowdata[7]));
				
				if (isStoredAlready(marketHistory)) return marketHistoryList;
				
				marketHistoryList.add(marketHistory);
			} catch (Exception e) {
				LOGGER.info("读取历史股价数据时出现错误，忽略该条记录。" + e.getLocalizedMessage());
			}
		}
		return marketHistoryList;
	}
	
	private boolean isStoredAlready(MarketHistory marketHistory) {
		MarketHistoryExample example = new MarketHistoryExample();
		Criteria criteria = example.createCriteria();
		criteria.andCodeEqualTo(marketHistory.getCode());
		criteria.andDateEqualTo(marketHistory.getDate());
		List<MarketHistory> profitStatementList = mapper.selectByExample(example);
		if (profitStatementList != null && profitStatementList.size() != 0) {
			LOGGER.info("当前股票的历史股价数据已经存在, 股票代码：" + marketHistory.getCode() + ", 日期：" + marketHistory.getDate());
			return true;
		}
		return false;
	}
	
	private Date getMarketHistoryDate(String text) throws FinancialReportException {
		try {
			return new SimpleDateFormat("yyyy-MM-dd").parse(text);
		} catch (ParseException e) {
			throw new FinancialReportException("历史股价日期格式化时出现错误，日期：" + text);
		}
	}
}
 